package service

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"chat.com/common"
	"chat.com/library"
	"chat.com/model"
	"chat.com/pkg/logger"
	"chat.com/server/wsserver/connection"
	"chat.com/setting"

	"github.com/redis/go-redis/v9"
)

/******************************************************************************/
var (
	accServerName string = setting.AccServerSetting.Name
	rpcServerName string = setting.RpcServerSetting.Name
	accServerAddr string = setting.AccServerSetting.Host
	rpcServerAddr string = setting.RpcServerSetting.Host
)

// ping
func PingHandler(client *connection.Connection, message []byte) (code int64, msg string, data interface{}) {
	code = common.OK
	msg = common.GetErrorMessage(code, "")
	logger.Info("websocket ping %s %s", client.Addr, message)
	data = "pong"
	return
}

// 用户登录
func WsLoginHandler(client *connection.Connection, message []byte) (code int64, msg string, data interface{}) {

	loginInfo := &common.WsLogin{}
	if err := json.Unmarshal(message, loginInfo); err != nil {
		code = common.ParameterIllegal
		fmt.Println("用户登录 解析数据失败", err)
		return
	}

	if loginInfo.Token != "123" {
		code = http.StatusUnauthorized
		msg = "用户没有登陆"
	}

	logger.Info("websocket 用户登录", "ServiceToken", loginInfo.Token)
	currentTime := uint64(time.Now().Unix())
	client.Login(loginInfo.AppId, loginInfo.UserId, currentTime)

	// 存储数据
	userOnline := model.NewUserOnline(
		accServerName, rpcServerName, accServerAddr, rpcServerAddr,
		loginInfo.AppId, loginInfo.UserId, client.Addr, currentTime,
	)

	if err := library.SetUserOnlineInfo(client.GetKey(), userOnline); err != nil {
		code = common.ServerError
		msg = common.GetErrorMessage(code, "")
		fmt.Println("用户登录 SetUserOnlineInfo", err)
		return
	}

	// 用户登陆事件通知
	connection.ConnectionManagerInstance.LoginCh <- client
	code = common.OK
	msg = common.GetErrorMessage(code, "")
	fmt.Println("用户登录 成功", client.Addr, loginInfo.UserId)
	return
}

// 心跳接口
func HeartbeatHandler(client *connection.Connection, message []byte) (code int64, msg string, data interface{}) {

	request := &common.WsHeartBeat{}
	if err := json.Unmarshal(message, request); err != nil {
		code = common.ParameterIllegal
		msg = common.GetErrorMessage(code, "")
		fmt.Println("心跳接口 解析数据失败", err)
		return
	}

	fmt.Println("webSocket_request 心跳接口", client.AppId, client.UserId)
	if !client.IsLogin() {
		fmt.Println("心跳接口 用户未登录", client.AppId, client.UserId)
		code = common.NotLoggedIn
		msg = common.GetErrorMessage(code, "")
		return
	}

	userOnline, err := library.GetUserOnlineInfo(client.GetKey())
	if err != nil {
		if err == redis.Nil {
			code = common.NotLoggedIn
			msg = common.GetErrorMessage(code, "")
			fmt.Println("心跳接口 用户未登录", client.AppId, client.UserId)
			return
		} else {
			code = common.ServerError
			msg = common.GetErrorMessage(code, ""+err.Error())
			fmt.Println("心跳接口 GetUserOnlineInfo", client.AppId, client.UserId, err)
			return
		}
	}

	currentTime := uint64(time.Now().Unix())
	client.Heartbeat(currentTime)
	userOnline.Heartbeat(currentTime)
	err = library.SetUserOnlineInfo(client.GetKey(), userOnline)
	if err != nil {
		code = common.StoreError
		msg = common.GetErrorMessage(code, "更新用户在线状态数据出现错误")
		fmt.Println("心跳接口 SetUserOnlineInfo", client.AppId, client.UserId, err)
		return
	}

	code = common.OK
	msg = common.GetErrorMessage(code, "")
	return
}

func SingleChatHandler(client *connection.Connection, requestData []byte) (code int64, msg string, data interface{}) {
	logger.Debug("call ChatHandler")

	// 解析单聊请求数据
	message := &common.WsSingleChatRequest{}
	if err := json.Unmarshal(requestData, message); err != nil {
		code = common.ParameterIllegal
		msg = common.GetErrorMessage(code, "聊天接口 解析数据失败")
		data = nil
		logger.Error("聊天接口 解析数据失败 client %d, data: %v\n", message.RecieverId, message)
		return
	}

	// 1. 持久化消息，返回给用户响应，若响应为不成功，直接返回；若成功，则继续向下执行
	code, result, err := PersistSingleChatMessage(message)
	client.Respond(code, []byte(fmt.Sprintf("%d", result.MsgId)))
	if code != common.OK {
		return code, common.GetErrorMessage(code, ""), nil
	}

	// 2. 发送消息给接收者
	code, result, err = SendSingleChatMessage(message)
	if code != common.OK {
		return code, common.GetErrorMessage(code, ""), nil
	}

	data = common.SingleChatResponse{MsgId: sendResult.MsgId}

	// 消息因为错误发送失败
	if err != nil {
		code = common.ServerError
		msg = common.GetErrorMessage(code, "消息发送失败: "+err.Error())
		logger.Error("消息发送失败 client %d, data: %v, error: %s\n", message.RecieverId, message, err.Error())
		return
	}

	// 用户离线，消息已离线缓存
	if !sendResult.Success && err == nil {
		code = common.OK
		msg = common.GetErrorMessage(code, "用户当前离线，用户上线后会推送您发的消息")
		logger.Error("用户当前离线，用户上线后会推送您发的消息 client %d, data: %v\n", message.RecieverId, message)
		return
	}

	// 成功
	code = common.OK
	msg = common.GetErrorMessage(code, "")
	logger.Debug("sent message to client %d, data: %v\n", message.RecieverId, message)
	return
}

/*func AckSingleChatHandler(client *connection.Connection, requestData []byte) (code int64, msg string, data interface{}) {
	logger.Debug("call ChatHandler")

	// 解析单聊请求数据
	message := &common.WsSingleChatAck{}
	if err := json.Unmarshal(requestData, message); err != nil {
		code = common.ParameterIllegal
		msg = common.GetErrorMessage(code, "聊天接口 解析数据失败")
		data = nil
		logger.Error("聊天接口 解析数据失败 client %d, data: %v\n", message.RecieverId, message)
		return
	}

	// 发送单聊消息，获取发送结果
	sendResult, err := SendSingleChatMessage(message)
	data = common.SingleChatResponse{MsgId: sendResult.MsgId}

	// 消息因为错误发送失败
	if err != nil {
		code = common.ServerError
		msg = common.GetErrorMessage(code, "消息发送失败: "+err.Error())
		logger.Error("消息发送失败 client %d, data: %v, error: %s\n", message.RecieverId, message, err.Error())
		return
	}

	// 用户离线，消息已离线缓存
	if !sendResult.Success && err == nil {
		code = common.UserOffline
		msg = common.GetErrorMessage(code, "用户当前离线，用户上线后会推送您发的消息")
		logger.Error("用户当前离线，用户上线后会推送您发的消息 client %d, data: %v\n", message.RecieverId, message)
		return
	}

	// 成功
	code = common.OK
	msg = common.GetErrorMessage(code, "")
	logger.Debug("sent message to client %d, data: %v\n", message.RecieverId, message)
	return
}*/
